// @flow
import { request, sign, config } from '../index'
export default class Service {
  constructor () {
    this.baseUrl = {}
    this.requestType = null
  }

  setup () {
    return Promise.resolve()
  }

  url (path) {
    return `${this.baseUrl[config.env]}${path}`
  }

  request (
    path,
    method,
    data,
    header,
    loading = false,
    cross = false
  ) {
    let defaultHeader = {}
    let defaultData = {}
    // PHP端服务.
    if (this.requestType === 'PHP') {
      const PHPHeaderData = {
        'Accept': 'application/json',
        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
      }
      defaultData.domain = window.location.host
      // 设置cookie跨域.
      cross = true
      defaultHeader = Object.assign({}, PHPHeaderData)
    }

    // Node端服务.
    const finalData = Object.assign(defaultData, data)

    if (this.requestType === 'Node') {
      const NodeHeaderData = {
        'Content-Type': 'application/json',
        'Vary-Client': 'web',
        'Sign': sign.creator(finalData)
      }
      defaultHeader = Object.assign({}, NodeHeaderData)
    }

    const finalHeader = Object.assign(defaultHeader, header)

    Object.keys(finalData).forEach((key) => (finalData[key] == null) && delete finalData[key])
    Object.keys(finalHeader).forEach((key) => (finalHeader[key] == null) && delete finalHeader[key])

    const url = this.url(path)
    const promise = request.request(
      url,
      method,
      finalData,
      finalHeader,
      loading,
      cross
    )
    return this.unpackResponse(promise, loading)
  }

  unpackResponse (
    promise,
    loading = false
  ) {
    return promise
      .then(res => {
        const wxData = res.data
        const wxStatusCode = res.statusCode

        if (wxStatusCode < 400) {
          return wxData
        } else {
          /**
           * ResponseStatus 说明:
           * => 1: 报错, ResponseMsg显示给用户
           * => 0: 数据返回成功
           * => -1: 报错, ResponseMsg不显示
           */
          // 4XX, 5XX 失败
          const responseStatus = wxData.ResponseStatus
          const errorMessage = wxData.ResponseMsg
          const errors = wxData.errors
          if (responseStatus === 1) {
            return Promise.reject(new Error(errors))
          } else {
            return Promise.reject(new Error(errorMessage))
          }
        }
      })
      .catch(err => {
        if (err.message === 'request:fail response data convert to UTF8 fail') {
          return
        }
        return Promise.reject(err)
      })
  }
}
